package com.java110.mall.acct.payment.business;

import com.alibaba.fastjson.JSONObject;
import com.java110.core.context.ICmdDataFlowContext;
import com.java110.core.factory.GenerateCodeFactory;
import com.java110.dto.payment.PaymentOrderDto;
import com.java110.dto.product.ProductSeckillDto;
import com.java110.dto.product.ProductSeckillOrderDto;
import com.java110.dto.shop.ShopDto;
import com.java110.dto.storeOrder.ResultComputeStoreOrderGoodsDto;
import com.java110.dto.storeOrder.ResultComputeStoreOrderPriceDto;
import com.java110.dto.user.UserDto;
import com.java110.intf.cart.IUnifiedOrderInnerServiceSMO;
import com.java110.intf.goods.IProductInnerServiceSMO;
import com.java110.intf.goods.IProductSeckillOrderV1InnerServiceSMO;
import com.java110.intf.goods.IProductSeckillV1InnerServiceSMO;
import com.java110.intf.shop.IShopInnerServiceSMO;
import com.java110.intf.user.IUserV1InnerServiceSMO;
import com.java110.mall.acct.payment.IPaymentBusiness;
import com.java110.po.product.ProductSeckillPo;
import com.java110.po.product.ProductSeckillOrderPo;
import com.java110.utils.cache.CommonCache;
import com.java110.utils.exception.CmdException;
import com.java110.utils.util.Assert;
import com.java110.utils.util.ListUtil;
import com.java110.utils.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("buyKillGoods")
public class BuyKillGoodsBusiness implements IPaymentBusiness {

    @Autowired
    private IShopInnerServiceSMO shopInnerServiceSMOImpl;

    @Autowired
    private IUnifiedOrderInnerServiceSMO unifiedOrderInnerServiceSMOImpl;

    @Autowired
    private IProductSeckillV1InnerServiceSMO productSeckillV1InnerServiceSMOImpl;

    @Autowired
    private IProductSeckillOrderV1InnerServiceSMO productSeckillOrderV1InnerServiceSMOImpl;

    @Autowired
    private IUserV1InnerServiceSMO userV1InnerServiceSMOImpl;

    @Autowired
    private IProductInnerServiceSMO productInnerServiceSMOImpl;


    @Override
    public PaymentOrderDto unified(ICmdDataFlowContext context, JSONObject reqJson) {

        String appId = context.getReqHeaders().get("app-id");
        String userId = context.getReqHeaders().get("user-id");

        Assert.hasKeyAndValue(reqJson, "shopId", "未包含商铺信息");
        Assert.hasKeyAndValue(reqJson, "killId", "未包含拼团ID");
        Assert.hasKeyAndValue(reqJson, "valueId", "未包含规格ID");
        Assert.hasKeyAndValue(reqJson, "productId", "未包含商品");
        Assert.hasKeyAndValue(reqJson, "addressId", "未包含地址");
        Assert.hasKeyAndValue(reqJson, "goodsNum", "未包含购买数量");
        reqJson.put("user-id", userId);//
        reqJson.put("app-id", appId);//

        UserDto userDto = new UserDto();
        userDto.setUserId(userId);
        List<UserDto> userDtos = userV1InnerServiceSMOImpl.queryUsers(userDto);

        Assert.listOnlyOne(userDtos, "用户不存在");
        /**
         * ?page=1&row=1&shopId=502022081626050001&cartType=3306
         * &productId=902022120101840004&valueId=912022120139430012&goodsNum=1&groupId=102022122018530001
         */

        //todo 查询商铺信息
        //计算服务费
        ShopDto shopDto = new ShopDto();
        shopDto.setShopId(reqJson.getString("shopId"));
        List<ShopDto> shopDtos = shopInnerServiceSMOImpl.queryShops(shopDto);

        Assert.listOnlyOne(shopDtos, "商铺不存在");
        shopDto = shopDtos.get(0);

        JSONObject paramIn = new JSONObject();
        paramIn.put("page", 1);
        paramIn.put("row", 1);
        paramIn.put("shopId", reqJson.getString("shopId"));
        paramIn.put("cartType", "3306");
        paramIn.put("productId", reqJson.getString("productId"));
        paramIn.put("valueId", reqJson.getString("valueId"));
        paramIn.put("goodsNum", reqJson.getString("goodsNum"));
        paramIn.put("killId", reqJson.getString("killId"));
        ResultComputeStoreOrderPriceDto resultComputeStoreOrderPriceDto = unifiedOrderInnerServiceSMOImpl.computeSkillProductPrice(reqJson);

        List<ResultComputeStoreOrderGoodsDto> goods = resultComputeStoreOrderPriceDto.getGoods();
        if (goods.get(0).getKillStock() < 1) {
            throw new CmdException("商品已经秒杀完了");
        }

        //todo 合规行校验
        ProductSeckillDto productSeckillDto = new ProductSeckillDto();
        productSeckillDto.setKillId(reqJson.getString("killId"));
        productSeckillDto.setShopId(reqJson.getString("shopId"));
        List<ProductSeckillDto> productSeckillDtos = productSeckillV1InnerServiceSMOImpl.queryProductSeckills(productSeckillDto);
        if (ListUtil.isNull(productSeckillDtos)) {
            throw new CmdException("秒杀不存在");
        }

        int oneCount = Integer.parseInt(productSeckillDtos.get(0).getOneCount());
        if (reqJson.getIntValue("goodsNum") > oneCount) {
            throw new CmdException("一次最多只能买" + oneCount + "个");
        }

        ProductSeckillOrderDto productSeckillOrderDto = new ProductSeckillOrderDto();
        productSeckillOrderDto.setKillId(reqJson.getString("killId"));
        productSeckillOrderDto.setBuyerId(userId);
        productSeckillOrderDto.setState(ProductSeckillOrderDto.STATE_COMPLETE);
        //todo 已经购买的数量
        int buyed = productSeckillOrderV1InnerServiceSMOImpl.queryProductSeckillOrdersCount(productSeckillOrderDto);
        int moreBuy = Integer.parseInt(productSeckillDtos.get(0).getTotalCount());
        if (buyed >= Integer.parseInt(productSeckillDtos.get(0).getTotalCount())) {
            throw new CmdException("最多可以买" + moreBuy);
        }


        String orderId = GenerateCodeFactory.getGeneratorId("11");

        //todo 生成秒杀订单，库存减一，锁单
        ProductSeckillOrderPo productSeckillOrderPo = new ProductSeckillOrderPo();
        productSeckillOrderPo.setOrderId(orderId);
        productSeckillOrderPo.setKillPrice(resultComputeStoreOrderPriceDto.getPayPrice() + "");
        productSeckillOrderPo.setCartId(GenerateCodeFactory.getGeneratorId("11"));
        productSeckillOrderPo.setProdName(goods.get(0).getProdName());
        productSeckillOrderPo.setKillId(reqJson.getString("killId"));
        productSeckillOrderPo.setRemark("秒杀订单");
        productSeckillOrderPo.setShopId(reqJson.getString("shopId"));
        productSeckillOrderPo.setBuyerId(userId);
        productSeckillOrderPo.setBuyerName(userDtos.get(0).getName());
        productSeckillOrderPo.setAddressId(reqJson.getString("addressId"));
        productSeckillOrderPo.setGoodsNum(reqJson.getString("goodsNum"));
        productSeckillOrderPo.setState(ProductSeckillOrderDto.STATE_WAIT);
        productSeckillOrderV1InnerServiceSMOImpl.saveProductSeckillOrder(productSeckillOrderPo);


        ProductSeckillPo productSeckillPo = new ProductSeckillPo();
        productSeckillPo.setKillId(reqJson.getString("killId"));
        long killStock = Long.parseLong(productSeckillDtos.get(0).getKillStock());
        killStock = killStock - reqJson.getLongValue("goodsNum");
        productSeckillPo.setKillStock(killStock + "");
        productSeckillV1InnerServiceSMOImpl.updateProductSeckill(productSeckillPo);


        String feeName = "购买商品";
        double money = resultComputeStoreOrderPriceDto.getPayPrice();

        PaymentOrderDto paymentOrderDto = new PaymentOrderDto();
        paymentOrderDto.setOrderId(orderId);
        paymentOrderDto.setMoney(money);
        paymentOrderDto.setName(feeName);

        if (StringUtil.isNumber(shopDto.getServiceFee()) && Double.parseDouble(shopDto.getServiceFee()) > 0) {
            paymentOrderDto.setProfitSharing(true);
        }

        reqJson.put("payAmount", money + "");
        reqJson.put("loginUserId", userId);
        CommonCache.setValue("BUY_KILL_GOODS" + orderId, reqJson.toJSONString(), CommonCache.PAY_DEFAULT_EXPIRE_TIME);


        return paymentOrderDto;
    }

    @Override
    public void notifyPayment(PaymentOrderDto paymentOrderDto, JSONObject reqJson) {

        String order = CommonCache.getAndRemoveValue("BUY_KILL_GOODS" + paymentOrderDto.getOrderId());
        if (StringUtil.isEmpty(order)) {
            return;// 说明已经处理过了 再不处理
        }
        JSONObject killInfo = JSONObject.parseObject(order);

        killInfo.put("orderId", paymentOrderDto.getOrderId());


        unifiedOrderInnerServiceSMOImpl.unifiedKillProductOrder(killInfo);


    }
}
